using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Mail;
using System.Text;

namespace EventLogMailer
{
    internal class Mailer
    {
        public static void SendMail(IEnumerable<string> recipients, ICollection<EventLogEntry> entries)
        {
            if (entries.Count == 0)
            {
                return;
            }

            var message = BuildMessage(recipients, entries);

            Program.TraceSource.TraceEvent(TraceEventType.Verbose, 0, string.Format("Sending mail to {0} with subject '{1}'.", message.To, message.Subject));

            using (var smtpClient = new SmtpClient())
            {
                smtpClient.Send(message);
            }
        }

        private static MailMessage BuildMessage(IEnumerable<string> recipients, ICollection<EventLogEntry> entries)
        {
            var message = new MailMessage { IsBodyHtml = false };
            foreach (var recipient in recipients)
            {
                message.To.Add(recipient);
            }

            if (entries.Count == 1)
            {
                var entry = entries.Single();

                message.Subject = String.Format("[{0}] {1}: {2}", Environment.MachineName, entry.Source, entry.Message.Substring(0, Math.Min(100, entry.Message.Length)));
                message.Body = BuildEntryText(entry);
            }
            else
            {
                var sources = String.Join(", ", entries.Select(e => e.Source).Distinct().OrderBy(s => s).ToArray());
                message.Subject = String.Format("[{0}] {1} events from {2}", Environment.MachineName, entries.Count, sources);

                var bodyBuilder = new StringBuilder();
                foreach (var entry in entries.OrderBy(e => e.TimeGenerated))
                {
                    bodyBuilder.Append(BuildEntryText(entry));
                    bodyBuilder.AppendLine();
                    bodyBuilder.AppendLine(new string('-', 80));
                    bodyBuilder.AppendLine();
                }

                message.Body = bodyBuilder.ToString();
            }
            return message;
        }

        private static string BuildEntryText(EventLogEntry entry)
        {
            var textBuilder = new StringBuilder();
            textBuilder.AppendFormat("Source: \t{0}\n", entry.Source);
            textBuilder.AppendFormat("EntryType: \t{0}\n", entry.EntryType);
            textBuilder.AppendFormat("Generated at: \t{0}\n", entry.TimeGenerated);
            textBuilder.AppendFormat("Written at: \t{0}\n", entry.TimeWritten);
            textBuilder.AppendFormat("UserName: \t{0}\n", entry.UserName);
            textBuilder.AppendLine();
            textBuilder.Append(entry.Message);
            return textBuilder.ToString();
        }
    }
}